/**
 * @file string_utils.c
 * @brief 通用字符串处理工具实现
 * @details 本文件实现了通用的字符串处理工具功能，包括安全的字符串操作、
 *          字符串转换、格式化、搜索替换、验证等功能。
 * 
 * @author zyb
 * @date 2025-09-26
 * @version 1.0
 * 
 * @see string_utils.h
 */

#include "string_utils.h"
#include "logger.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <limits.h>

// 定义模块名称
#define LOG_MODULE_NAME "STRING_UTILS"

/* ==================== 字符串处理函数实现 ==================== */

/**
 * @brief 安全字符串复制
 */
string_error_t safe_strcpy(char* dest, const char* src, size_t dest_size) {
    if (!dest || !src || dest_size == 0) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    size_t src_len = strlen(src);
    if (src_len >= dest_size) {
        return STRING_ERROR_BUFFER_OVERFLOW;
    }
    
    strcpy(dest, src);
    return STRING_SUCCESS;
}

/**
 * @brief 安全字符串连接
 */
string_error_t safe_strcat(char* dest, const char* src, size_t dest_size) {
    if (!dest || !src || dest_size == 0) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    size_t dest_len = strlen(dest);
    size_t src_len = strlen(src);
    
    if (dest_len + src_len >= dest_size) {
        return STRING_ERROR_BUFFER_OVERFLOW;
    }
    
    strcat(dest, src);
    return STRING_SUCCESS;
}

/**
 * @brief 安全字符串比较
 */
int safe_strcmp(const char* str1, const char* str2, size_t max_len) {
    if (!str1 || !str2) {
        return -1;
    }
    
    return strncmp(str1, str2, max_len);
}

/**
 * @brief 安全字符串长度计算
 */
size_t safe_strlen(const char* str, size_t max_len) {
    if (!str) {
        return 0;
    }
    
    size_t len = strlen(str);
    return (len > max_len) ? max_len : len;
}

/**
 * @brief 字符串转换为小写
 */
string_error_t str_to_lower(char* str) {
    if (!str) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    for (char* p = str; *p; p++) {
        *p = tolower(*p);
    }
    return STRING_SUCCESS;
}

/**
 * @brief 字符串转换为大写
 */
string_error_t str_to_upper(char* str) {
    if (!str) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    for (char* p = str; *p; p++) {
        *p = toupper(*p);
    }
    return STRING_SUCCESS;
}

/**
 * @brief 去除字符串首尾空白字符
 */
string_error_t str_trim(char* str) {
    if (!str) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    str_ltrim(str);
    str_rtrim(str);
    return STRING_SUCCESS;
}

/**
 * @brief 去除字符串左侧空白字符
 */
string_error_t str_ltrim(char* str) {
    if (!str) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    char* start = str;
    while (isspace(*start)) {
        start++;
    }
    
    if (start != str) {
        memmove(str, start, strlen(start) + 1);
    }
    return STRING_SUCCESS;
}

/**
 * @brief 去除字符串右侧空白字符
 */
string_error_t str_rtrim(char* str) {
    if (!str) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    char* end = str + strlen(str) - 1;
    while (end >= str && isspace(*end)) {
        end--;
    }
    *(end + 1) = '\0';
    return STRING_SUCCESS;
}

/* ==================== 字符串转换函数实现 ==================== */

/**
 * @brief 字符串转整数
 */
string_error_t str_to_int(const char* str, int* value, int base) {
    if (!str || !value) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    char* endptr;
    long result = strtol(str, &endptr, base);
    
    if (*endptr != '\0') {
        return STRING_ERROR_INVALID_FORMAT;
    }
    
    if (result < INT_MIN || result > INT_MAX) {
        return STRING_ERROR_INVALID_PARAM;
    }
    
    *value = (int)result;
    return STRING_SUCCESS;
}

/**
 * @brief 字符串转长整数
 */
string_error_t str_to_long(const char* str, long* value, int base) {
    if (!str || !value) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    char* endptr;
    *value = strtol(str, &endptr, base);
    
    if (*endptr != '\0') {
        return STRING_ERROR_INVALID_FORMAT;
    }
    
    return STRING_SUCCESS;
}

/**
 * @brief 字符串转无符号整数
 */
string_error_t str_to_uint(const char* str, unsigned int* value, int base) {
    if (!str || !value) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    char* endptr;
    unsigned long result = strtoul(str, &endptr, base);
    
    if (*endptr != '\0') {
        return STRING_ERROR_INVALID_FORMAT;
    }
    
    if (result > UINT_MAX) {
        return STRING_ERROR_INVALID_PARAM;
    }
    
    *value = (unsigned int)result;
    return STRING_SUCCESS;
}

/**
 * @brief 字符串转浮点数
 */
string_error_t str_to_float(const char* str, float* value) {
    if (!str || !value) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    char* endptr;
    double result = strtod(str, &endptr);
    
    if (*endptr != '\0') {
        return STRING_ERROR_INVALID_FORMAT;
    }
    
    *value = (float)result;
    return STRING_SUCCESS;
}

/**
 * @brief 字符串转双精度浮点数
 */
string_error_t str_to_double(const char* str, double* value) {
    if (!str || !value) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    char* endptr;
    *value = strtod(str, &endptr);
    
    if (*endptr != '\0') {
        return STRING_ERROR_INVALID_FORMAT;
    }
    
    return STRING_SUCCESS;
}

/**
 * @brief 整数转字符串
 */
string_error_t int_to_str(int value, char* str, size_t str_size, int base) {
    if (!str || str_size == 0) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    // 抑制未使用参数警告
    (void)base;
    
    int result = snprintf(str, str_size, "%d", value);
    if (result < 0 || (size_t)result >= str_size) {
        return STRING_ERROR_BUFFER_OVERFLOW;
    }
    
    return STRING_SUCCESS;
}

/**
 * @brief 无符号整数转字符串
 */
string_error_t uint_to_str(unsigned int value, char* str, size_t str_size, int base) {
    if (!str || str_size == 0) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    // 抑制未使用参数警告
    (void)base;
    
    int result = snprintf(str, str_size, "%u", value);
    if (result < 0 || (size_t)result >= str_size) {
        return STRING_ERROR_BUFFER_OVERFLOW;
    }
    
    return STRING_SUCCESS;
}

/**
 * @brief 浮点数转字符串
 */
string_error_t float_to_str(float value, char* str, size_t str_size, int precision) {
    if (!str || str_size == 0) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    char format[32];
    snprintf(format, sizeof(format), "%%.%df", precision);
    
    int result = snprintf(str, str_size, format, value);
    if (result < 0 || (size_t)result >= str_size) {
        return STRING_ERROR_BUFFER_OVERFLOW;
    }
    
    return STRING_SUCCESS;
}

/**
 * @brief 双精度浮点数转字符串
 */
string_error_t double_to_str(double value, char* str, size_t str_size, int precision) {
    if (!str || str_size == 0) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    char format[32];
    snprintf(format, sizeof(format), "%%.%dlf", precision);
    
    int result = snprintf(str, str_size, format, value);
    if (result < 0 || (size_t)result >= str_size) {
        return STRING_ERROR_BUFFER_OVERFLOW;
    }
    
    return STRING_SUCCESS;
}

/* ==================== 字符串格式化函数实现 ==================== */

/**
 * @brief 安全字符串格式化
 */
string_error_t safe_sprintf(char* str, size_t str_size, const char* format, ...) {
    if (!str || !format || str_size == 0) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    va_list args;
    va_start(args, format);
    int result = vsnprintf(str, str_size, format, args);
    va_end(args);
    
    if (result < 0 || (size_t)result >= str_size) {
        return STRING_ERROR_BUFFER_OVERFLOW;
    }
    
    return STRING_SUCCESS;
}

/**
 * @brief 安全字符串追加格式化
 */
string_error_t safe_strcatf(char* str, size_t str_size, const char* format, ...) {
    if (!str || !format || str_size == 0) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    size_t current_len = strlen(str);
    if (current_len >= str_size) {
        return STRING_ERROR_BUFFER_OVERFLOW;
    }
    
    va_list args;
    va_start(args, format);
    int result = vsnprintf(str + current_len, str_size - current_len, format, args);
    va_end(args);
    
    if (result < 0 || (size_t)(current_len + result) >= str_size) {
        return STRING_ERROR_BUFFER_OVERFLOW;
    }
    
    return STRING_SUCCESS;
}

/* ==================== 字符串搜索和替换函数实现 ==================== */

/**
 * @brief 查找子字符串
 */
char* str_find(const char* str, const char* substr) {
    if (!str || !substr) {
        return NULL;
    }
    
    return strstr(str, substr);
}

/**
 * @brief 查找字符
 */
char* str_find_char(const char* str, char ch) {
    if (!str) {
        return NULL;
    }
    
    return strchr(str, ch);
}

/**
 * @brief 替换字符串中的子字符串
 */
string_error_t str_replace(char* str, size_t str_size, const char* old_substr, const char* new_substr) {
    if (!str || !old_substr || !new_substr || str_size == 0) {
        return STRING_ERROR_NULL_POINTER;
    }
    
    char* pos = strstr(str, old_substr);
    if (!pos) {
        return STRING_SUCCESS; // 没有找到要替换的子字符串
    }
    
    size_t old_len = strlen(old_substr);
    size_t new_len = strlen(new_substr);
    size_t current_len = strlen(str);
    
    if (current_len - old_len + new_len >= str_size) {
        return STRING_ERROR_BUFFER_OVERFLOW;
    }
    
    memmove(pos + new_len, pos + old_len, current_len - (pos - str) - old_len + 1);
    memcpy(pos, new_substr, new_len);
    
    return STRING_SUCCESS;
}

/* ==================== 字符串验证函数实现 ==================== */

/**
 * @brief 验证字符串是否为数字
 */
int str_is_numeric(const char* str) {
    if (!str || *str == '\0') {
        return 0;
    }
    
    for (const char* p = str; *p; p++) {
        if (!isdigit(*p)) {
            return 0;
        }
    }
    return 1;
}

/**
 * @brief 验证字符串是否为字母
 */
int str_is_alpha(const char* str) {
    if (!str || *str == '\0') {
        return 0;
    }
    
    for (const char* p = str; *p; p++) {
        if (!isalpha(*p)) {
            return 0;
        }
    }
    return 1;
}

/**
 * @brief 验证字符串是否为字母数字
 */
int str_is_alnum(const char* str) {
    if (!str || *str == '\0') {
        return 0;
    }
    
    for (const char* p = str; *p; p++) {
        if (!isalnum(*p)) {
            return 0;
        }
    }
    return 1;
}

/**
 * @brief 验证字符串是否为空或只包含空白字符
 */
int str_is_empty(const char* str) {
    if (!str) {
        return 1;
    }
    
    for (const char* p = str; *p; p++) {
        if (!isspace(*p)) {
            return 0;
        }
    }
    return 1;
}
